package com.tsfyun.scm.service.impl.wms;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tsfyun.common.base.enums.BillTypeEnum;
import com.tsfyun.common.base.enums.SerialNumberTypeEnum;
import com.tsfyun.common.base.enums.domain.DeliveryNoteStatusEnum;
import com.tsfyun.common.base.enums.domain.DomainOprationEnum;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.security.SecurityUtil;
import com.tsfyun.common.base.support.DomainStatus;
import com.tsfyun.scm.dto.wms.DeliveryNoteQTO;
import com.tsfyun.scm.entity.wms.DeliveryNote;
import com.tsfyun.scm.entity.wms.DeliveryNoteMember;
import com.tsfyun.scm.mapper.wms.DeliveryNoteMapper;
import com.tsfyun.scm.service.order.IOrderReceivingNoteMemberService;
import com.tsfyun.scm.service.system.ISerialNumberService;
import com.tsfyun.scm.service.wms.IDeliveryNoteMemberService;
import com.tsfyun.scm.service.wms.IDeliveryNoteService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.vo.order.OrderReceivingBindVO;
import com.tsfyun.scm.vo.wms.DeliveryNoteMemberVO;
import com.tsfyun.scm.vo.wms.DeliveryNotePlusDetailVO;
import com.tsfyun.scm.vo.wms.DeliveryNoteVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 出库单 服务实现类
 * </p>
 *
 *
 * @since 2020-04-24
 */
@Service
public class DeliveryNoteServiceImpl extends ServiceImpl<DeliveryNote> implements IDeliveryNoteService {

    @Autowired
    private DeliveryNoteMapper deliveryNoteMapper;
    @Autowired
    private IDeliveryNoteMemberService deliveryNoteMemberService;
    @Autowired
    private IOrderReceivingNoteMemberService orderReceivingNoteMemberService;
    @Autowired
    private ISerialNumberService serialNumberService;
    @Autowired
    private Snowflake snowflake;

    @Override
    public PageInfo<DeliveryNoteVO> pageList(DeliveryNoteQTO qto) {
        PageHelper.startPage(qto.getPage(),qto.getLimit());
        Map<String,Object> params = beanMapper.map(qto,Map.class);
        params.put("billType", BillTypeEnum.IMP.getCode());
        List<DeliveryNoteVO> list = deliveryNoteMapper.list(params);
        return new PageInfo<>(list);
    }

    @Override
    public DeliveryNotePlusDetailVO detail(Long id, String operation) {
        DeliveryNote deliveryNote = super.getById(id);
        Optional.ofNullable(deliveryNote).orElseThrow(()->new ServiceException("出库单不存在"));
        DomainStatus.getInstance().check(DomainOprationEnum.of(operation),deliveryNote.getStatusId());
        //获取出库单明细信息
        List<DeliveryNoteMemberVO> members = deliveryNoteMemberService.findByDeliveryNoteId(id);
        return new DeliveryNotePlusDetailVO(beanMapper.map(deliveryNote,DeliveryNoteVO.class),members);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void overseasDeliveryOrder(List<String> orderNo, LocalDateTime deliveryDate) {
        List<OrderReceivingBindVO> orbVOList = orderReceivingNoteMemberService.queryOrderReceivingBind(orderNo);
        Map<String,List<OrderReceivingBindVO>> orbMap = Maps.newLinkedHashMap();
        orbVOList.stream().forEach(orb ->{
            String key = orb.getWarehouseId()+"||"+orb.getOrderNo();
            List<OrderReceivingBindVO> itemList = orbMap.get(key);
            if(CollUtil.isEmpty(itemList)){
                itemList = Lists.newArrayList();
            }
            itemList.add(orb);
            orbMap.put(key,itemList);
        });
        List<DeliveryNote> deliveryNoteList = Lists.newArrayList();//主单
        List<DeliveryNoteMember> deliveryNoteMemberList = Lists.newArrayList();//明细
        String createBy = SecurityUtil.getCurrentPersonIdAndName();
        LocalDateTime now = LocalDateTime.now();
        for(Map.Entry<String,List<OrderReceivingBindVO>> map : orbMap.entrySet()){
            List<OrderReceivingBindVO> bindVOS = map.getValue();
            OrderReceivingBindVO firstItem = bindVOS.get(0);
            //生成出库单
            DeliveryNote deliveryNote = new DeliveryNote();
            deliveryNote.setId(snowflake.nextId());
            deliveryNote.setDocNo(serialNumberService.generateDocNo(SerialNumberTypeEnum.DELIVERY_NOTE));
            deliveryNote.setBillType(BillTypeEnum.IMP.getCode());
            deliveryNote.setCustomerId(firstItem.getCustomerId());
            deliveryNote.setDeliveryDate(deliveryDate);
            deliveryNote.setStatusId(DeliveryNoteStatusEnum.OUTBOUND.getCode());
            deliveryNote.setWarehouseId(firstItem.getWarehouseId());
            deliveryNote.setMemo(String.format("根据订单【%s】自动生成",firstItem.getOrderNo()));
            deliveryNote.setDocumentMaker("系统");
            deliveryNote.setIsAbroad(Boolean.TRUE);
            deliveryNote.setOrderNo(firstItem.getOrderNo());
            deliveryNote.setCreateBy(createBy);
            deliveryNote.setUpdateBy(createBy);
            deliveryNote.setDateCreated(now);
            deliveryNote.setDateUpdated(now);
            deliveryNoteList.add(deliveryNote);

            //出库单明细
            bindVOS.stream().forEach(member ->{
                DeliveryNoteMember dnm = new DeliveryNoteMember();
                dnm.setId(snowflake.nextId());
                dnm.setDeliveryNoteId(deliveryNote.getId());
                dnm.setReceivingNoteMemberId(member.getReceivingNoteMemberId());
                dnm.setModel(member.getModel());
                dnm.setBrand(member.getBrand());
                dnm.setName(member.getName());
                dnm.setSpec(member.getSpec());
                dnm.setGoodsCode(member.getGoodsCode());
                dnm.setCountry(member.getCountry());
                dnm.setCountryName(member.getCountryName());
                dnm.setUnitCode(member.getUnitCode());
                dnm.setUnitName(member.getUnitName());
                dnm.setQuantity(member.getQuantity());
                dnm.setNetWeight(member.getNetWeight());
                dnm.setGrossWeight(member.getGrossWeight());
                dnm.setCartonNum(member.getCartonNum());
                dnm.setCartonNo(member.getCartonNo());
                deliveryNoteMemberList.add(dnm);
            });
        }
        //批量保存入库单主单
        super.savaBatch(deliveryNoteList);
        //批量保存明细
        deliveryNoteMemberService.savaBatch(deliveryNoteMemberList);
        //标识绑定明细已经出库
        orderReceivingNoteMemberService.identificationIsIssued(orderNo,Boolean.TRUE);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByReceivingNoteMember(List<Long> receivingNoteMemberIds) {
        List<Long> deliveryNoteIds = Lists.newArrayList();
        receivingNoteMemberIds.stream().forEach(mid ->{
            DeliveryNoteMember deliveryNoteMember = deliveryNoteMemberService.findByReceivingNoteMemberId(mid);
            if(Objects.nonNull(deliveryNoteMember)){
                if(!deliveryNoteIds.contains(deliveryNoteMember.getDeliveryNoteId())){
                    deliveryNoteIds.add(deliveryNoteMember.getDeliveryNoteId());
                }
                deliveryNoteMemberService.removeById(deliveryNoteMember.getId());
            }
        });
        if(CollUtil.isNotEmpty(deliveryNoteIds)){
            deliveryNoteIds.stream().forEach(did ->{
                List<DeliveryNoteMemberVO> memberVOList = deliveryNoteMemberService.findByDeliveryNoteId(did);
                if(CollUtil.isEmpty(memberVOList)){
                    super.removeById(did);
                }
            });
        }
    }
}
